using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Forms;
using System.Xml;
using System.Text.RegularExpressions;
using System.Collections;
using System.Threading;

namespace DiscuzRobot
{
    public class SiteTreeNode
    {
        private Robot rb;
        public SiteTreeNode()
        {
            rb = new Robot();
        }

        public SortedList TreeAndDocumentlist = new SortedList();
        public SiteNode TreeNodes;

        public enum LoadMode { XML, WEB, NONE };
        public SiteNode InitializeTree_WEB()
        {
            TreeNodes = new SiteNode(SiteInfo.Instance.SiteName);
            TreeNodes.Tag = "";
            TreeNodes.NodeClass = TreeNodes.Get_E_Name(E_NodeClass.Root);

            //rb.Login(new WaterArmyData( SiteInfo.Instance));
            string html = rb.Get_Html(new UrlInfo(SiteInfo.Instance));
            MatchCollection mc = Regex.Matches(html, @"forum.php\?gid=\s*\d*\s*"".*</a>");
            foreach (Match m in mc)
            {
                string tme = Regex.Replace(m.ToString(), @"\s+", "");
                tme = Regex.Replace(tme.ToString(), @"</a>", "");
                tme = Regex.Replace(tme.ToString(), @""".*"">|</a>", " ");
                string[] ary = Regex.Split(tme, @"\s");

                SiteNode tn = new SiteNode(ary[1]);
                tn.Tag = ary[0];
                tn.NodeClass = tn.Get_E_Name(E_NodeClass.FenQu);
                TreeNodes.Nodes.Add(tn);
                html = rb.Get_Html(new UrlInfo(tn));
                mc = Regex.Matches(html, @"forum.php\?mod=forumdisplay\s*.*</a>");
                foreach (Match mm in mc)
                {
                    if (mm.ToString().Contains("<img")) continue;
                    tme = Regex.Replace(mm.ToString(), @"\s*", "");
                    tme = Regex.Replace(tme.ToString(), @"""\s*>|"".*"">|</a>", " ");
                    ary = Regex.Split(tme, @"\s");
                    SiteNode tn1 = new SiteNode(ary[1]);
                    tn1.Tag = ary[0];
                    tn1.NodeClass = tn1.Get_E_Name(E_NodeClass.BanKuai);
                    tn.Nodes.Add(tn1);
                }

            }
            ImportTreeView(TreeNodes.Nodes);

            return TreeNodes;


        }
        public SiteNode InitializeTree_XML()
        {
            XmlDocument xmldoc = new XmlDocument();
            xmldoc.Load(Global.APP_SiteTreeXMLPath);
            XmlElement root = (XmlElement)xmldoc.SelectSingleNode("SiteTree");

            TreeNodes = new SiteNode();
            TreeNodes.Text = root.Attributes["NodeName"].Value;
            TreeNodes.Tag = root.Attributes["NodeTag"].Value;
            TreeNodes.NodeClass = root.Attributes["NodeClass"].Value;


            foreach (XmlElement XmlE in root.ChildNodes)
            {
                SiteNode TreeNodes1 = new SiteNode();
                TreeNodes1.Text = XmlE.Attributes["NodeName"].Value;
                TreeNodes1.Tag = XmlE.Attributes["NodeTag"].Value;
                TreeNodes1.NodeClass = XmlE.Attributes["NodeClass"].Value;
                TreeNodes.Nodes.Add(TreeNodes1);
                ReadXmlElement(XmlE.ChildNodes, TreeNodes1);
            }
            return TreeNodes;
        }

        public void ImportTreeView(TreeNodeCollection tc)
        {
            XmlTextWriter tw;
            tw = new XmlTextWriter(Global.APP_SiteTreeXMLPath, null);
            tw.Formatting = Formatting.Indented;
            tw.WriteStartDocument();

            tw.WriteStartElement("SiteTree");
            tw.WriteAttributeString("NodeTag", TreeNodes.Tag.ToString());
            tw.WriteAttributeString("NodeName", TreeNodes.Text);
            tw.WriteAttributeString("NodeClass", TreeNodes.NodeClass);

            foreach (SiteNode Node in tc)
            {
                string objid = Node.Tag.ToString();
                string objName = Node.Text;

                tw.WriteStartElement(Node.NodeClass);
                tw.WriteAttributeString("NodeTag", Node.Tag.ToString());
                tw.WriteAttributeString("NodeName", Node.Text);
                tw.WriteAttributeString("NodeClass", Node.NodeClass);

                ForeachNode(Node.Nodes, tw);
                tw.WriteEndElement();
            }

            tw.WriteEndElement();
            tw.WriteEndDocument();
            tw.Flush();
            tw.Close();

        }
        public void ForeachNode(TreeNodeCollection tc, XmlTextWriter tw)
        {
            foreach (SiteNode Node in tc)
            {
                string objid = Node.Tag.ToString();
                string objName = Node.Text;

                tw.WriteStartElement(Node.NodeClass);
                tw.WriteAttributeString("NodeTag", Node.Tag.ToString());
                tw.WriteAttributeString("NodeName", Node.Text);
                tw.WriteAttributeString("NodeClass", Node.NodeClass);

                if (Node.Nodes.Count != 0)
                    ForeachNode(Node.Nodes, tw);
                tw.WriteEndElement();
            }
        }

        public TreeNode InitializeTreeNode(LoadMode lm)
        {
            if (lm == LoadMode.WEB)
            {
                TreeNodes = InitializeTree_WEB();
            }else if (lm == LoadMode.XML)
            {
                if (!System.IO.File.Exists(Global.APP_SiteTreeXMLPath))
                {
                    TreeNodes = new SiteNode(SiteInfo.Instance.SiteName);
                    TreeNodes.NodeClass = E_NodeClass.Root.ToString() ;
                }else
                    TreeNodes = InitializeTree_XML();
            }

            //ReadDocument();
            if(Global.GetDoucmentByAppRun)
            new Thread(new ThreadStart(ReadDocument)).Start();


            return TreeNodes;
        }


        public void ReadXmlElement(XmlNodeList nodes, SiteNode tn)
        {
            foreach (XmlElement xx in nodes)
            {
                SiteNode cn = new SiteNode();
                cn.Text = xx.GetAttribute("NodeName");
                cn.Tag = xx.GetAttribute("NodeTag");
                cn.NodeClass = xx.GetAttribute("NodeClass");
                tn.Nodes.Add(cn);
                if (xx.HasChildNodes)
                    ReadXmlElement(xx.ChildNodes, cn);
            }
        }

        public void ReadDocument()
        {
            foreach (SiteNode tn in TreeNodes.Nodes)
            {
                foreach (SiteNode tn1 in tn.Nodes)
                {
                    List<UrlInfo> duclist = rb.Read_doculist(new UrlInfo(tn1));
                    Add_TreeAndDocumentlist(tn1.Text, duclist);
                }
            }
        }

        public void ReadDocumentBySelectNode(string name)
        {
            foreach (SiteNode tn in TreeNodes.Nodes)
            {
                foreach (SiteNode tn1 in tn.Nodes)
                {
                    if (tn1.Text != name)
                        continue;
                    else
                    {
                        List<UrlInfo> duclist = rb.Read_doculist(new UrlInfo(tn1));
                        Add_TreeAndDocumentlist(tn1.Text, duclist);
                        return;
                    }
                }

            }

        }
        public void Add_TreeAndDocumentlist(object key, object value)
        {
            if (TreeAndDocumentlist.ContainsKey(key))
                TreeAndDocumentlist.Remove(key);
            TreeAndDocumentlist.Add(key, value);

        }
        public List<UrlInfo> GetDeculist(string name)
        {
            if (!TreeAndDocumentlist.ContainsKey(name))
                return null;
            List<UrlInfo> res = (List<UrlInfo>)TreeAndDocumentlist.GetByIndex(TreeAndDocumentlist.IndexOfKey(name));
            return res;

        }
        public void GetDeculist(TreeNodeCollection tc, ref List<UrlInfo> res)
        {
            //List<UrlInfo> res = new List<UrlInfo>();
            foreach (SiteNode sn in tc)
            {
                if (sn.Nodes.Count == 0)
                {
                    List<UrlInfo> lsurlinfo = GetDeculist(sn.Text);
                    res.AddRange(lsurlinfo.ToArray());
                }
                else
                {
                    GetDeculist(sn.Nodes, ref res);
                }
            }
        }
        public void GetFenQuList(TreeNodeCollection tc, ref List<UrlInfo> res)
        {
            foreach (SiteNode sn in tc)
            {
                if ((E_NodeClass)Enum.Parse(typeof(E_NodeClass), sn.NodeClass) == DiscuzRobot.E_NodeClass.BanKuai)
                {
                    res.Add(new UrlInfo(sn.Text, sn.Tag as string));
                }
                else
                {
                    GetFenQuList(sn.Nodes, ref res);
                }
            }
        }
    }
    public enum E_NodeClass { Root, BanKuai, FenQu, None };

    public class SiteNode : TreeNode
    {
        public SiteNode() : base() { }
        public SiteNode(string text)
            : base(text)
        { }
        public string NodeClass;


        public string Get_E_Name(E_NodeClass e)
        {
            return Enum.GetName(typeof(E_NodeClass), e);
        }
    }

}
